package com.ocom.app.controller;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.ocom.app.feignclient.CompanyFeignClient;
import com.ocom.app.feignclient.PayConfigFeignClient;
import com.ocom.app.feignclient.WebApiFeignClient;
import com.ocom.app.vo.LoginResultVo;
import com.ocom.app.vo.MainAccountBindVo;
import com.ocom.app.vo.ResetPwdVo;
import com.ocom.common.constant.CompanyServiceUrl;
import com.ocom.common.dto.UnitsPageModifyDto;
import com.ocom.common.entity.card.EntityXfMerchantInfo;
import com.ocom.common.entity.company.EntityDeviceUserBind;
import com.ocom.common.entity.master.EntityCompanyList;
import com.ocom.common.entity.master.EntityMngUserInfo;
import com.ocom.common.enums.ResultEnum;
import com.ocom.common.resp.Result;
import com.ocom.common.utils.ResultUtil;
import com.ocom.common.utils.StringUtil;
import com.ocom.common.utils.pwd.HandlePasswordUtil;
import com.ocom.redis.util.RedisUtil;
import com.ocom.security.authentication.YoCiUser;
import com.ocom.security.utils.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@RestController
public class DeviceUserBindController {


  @Autowired
  private CompanyFeignClient companyFeignClient;

  @Autowired
  private WebApiFeignClient aiotWebFeignClient;

  @Autowired
  private PayConfigFeignClient payConfigFeignClient;

  @Autowired
  private RedisUtil redisUtil;

  @Autowired
  private RedisTemplate redisTemplate;


  @Autowired
  private DiscoveryClient discoveryClient;

  @GetMapping(CompanyServiceUrl.URL_mainAccountList)
  public Result mainAccountList(@RequestParam("deviceId") String deviceId) {
    YoCiUser yoCiUser = SecurityUtils.getYoCiUser();
    return ResultUtil.success(companyFeignClient.mainAccountList(yoCiUser.getComId(), deviceId).getData());
  }

  @GetMapping(CompanyServiceUrl.URL_switchAccount)
  public Result switchAccount(@RequestParam("userId") String userId, @RequestParam("deviceid") String deviceid) {
    YoCiUser yoCiUser = SecurityUtils.getYoCiUser();
    return ResultUtil.success(companyFeignClient.switchAccount(yoCiUser.getComId(), userId, deviceid).getData());
  }


  @PostMapping(CompanyServiceUrl.URL_resetPwd)
  public Result resetPwd(@RequestBody ResetPwdVo resetPwdVo) {
    // 校验手机号是否合法
    if (StringUtil.isEmpty(resetPwdVo.getTelephone()) || !StringUtil.isPhone(resetPwdVo.getTelephone())) {
      return ResultUtil.error(ResultEnum.Err_4705);
    }

    String codeKey = "send:telephone:code:";

    String code = (String) redisTemplate.opsForValue().get(codeKey + resetPwdVo.getTelephone());

    if (ObjectUtil.isEmpty(code)) {
      return ResultUtil.error(ResultEnum.Err_4703);
    }

    if (!resetPwdVo.getSmsCode().equals(String.valueOf(code))) {
      return ResultUtil.error(ResultEnum.Err_4703);
    }

    if (!resetPwdVo.getRepeatPwd().equals(resetPwdVo.getNewPwd())) {
      return ResultUtil.error(ResultEnum.Err_3112);
    }
    if (!HandlePasswordUtil.isWeekPassword(resetPwdVo.getNewPwd())) {
      return ResultUtil.error(ResultEnum.Err_3107);
    }
    // 验证通过删除验证码
    if (!StringUtils.equalsAnyIgnoreCase(code, "123456", "8888")) {
      redisUtil.del(codeKey + resetPwdVo.getTelephone());
    }

    UnitsPageModifyDto unitsPageModifyDto = new UnitsPageModifyDto();
    unitsPageModifyDto.setPassword(resetPwdVo.getNewPwd());

    return ResultUtil.success(aiotWebFeignClient.UserPageModify(unitsPageModifyDto).getData());
  }


  // 3.1.5.绑定主帐号(/appapi/main-account/bind)
  @PostMapping("/main-account/bind")
  public Result mainAccountBind(@RequestBody MainAccountBindVo mainAccountBindVo) {
    // 校验手机号是否合法
    if (StringUtil.isEmpty(mainAccountBindVo.getTelephone()) || !StringUtil.isPhone(mainAccountBindVo.getTelephone())) {
      return ResultUtil.error(ResultEnum.Err_4705);
    }
    YoCiUser yoCiUser = SecurityUtils.getYoCiUser();

    Result userByNameAndRole = companyFeignClient.getAccountAndRole(mainAccountBindVo.getTelephone(), null);
    EntityMngUserInfo entityMngUserInfo = JSON.parseObject(JSON.toJSONString(userByNameAndRole.getData()), EntityMngUserInfo.class);
    if (Objects.isNull(entityMngUserInfo)) {
      // 如返回为空，则提示 手机未绑定商户管理员
      return ResultUtil.error(ResultEnum.Err_4702);
    }


    String url = getOauthUrl();
    MultipartEntityBuilder builder = MultipartEntityBuilder.create();
    builder.addTextBody("telephone", mainAccountBindVo.getTelephone());
    builder.addTextBody("smsCode", mainAccountBindVo.getSmsCode());
    builder.addTextBody("grant_type", "app_auth_code");
    builder.addTextBody("client_id", "client_8");
    builder.addTextBody("client_secret", "123456");
    String loginResult = sendPostFormData(url, builder);
    System.out.println(loginResult);
    LoginResultVo map = JSON.parseObject(loginResult, LoginResultVo.class);
    System.out.println(map.getData());
    if (ObjectUtil.isEmpty(map) || !map.getCode().equals("200")) {
      return ResultUtil.error(ResultEnum.Err_3113);
    }

    Result companyListInfoOne = companyFeignClient.getCompanyListInfoOne(entityMngUserInfo.getComId());
    EntityCompanyList entityCompanyList = JSON.parseObject(JSON.toJSONString(companyListInfoOne.getData()), EntityCompanyList.class);

    Result getMerchInfo = payConfigFeignClient.GetMerchInfo(entityMngUserInfo.getComId(),
        entityMngUserInfo.getBnsId().intValue());

    EntityXfMerchantInfo entityXfMerchantInfo = JSON.parseObject(JSON.toJSONString(getMerchInfo.getData()), EntityXfMerchantInfo.class);

    EntityDeviceUserBind entityDeviceUserBind = new EntityDeviceUserBind();
    entityDeviceUserBind.setDeviceId(mainAccountBindVo.getDeviceId());
    entityDeviceUserBind.setUserId(entityMngUserInfo.getId());
    entityDeviceUserBind.setUserName(entityMngUserInfo.getUserName());
    entityDeviceUserBind.setLoginJson(map.getData());
    entityDeviceUserBind.setCompanyName(entityCompanyList.getComName());
    entityDeviceUserBind.setMerchantName(entityXfMerchantInfo.getMerchName());
    companyFeignClient.mainAccountBindDeviceUserBind(yoCiUser.getComId(), entityDeviceUserBind);

    return ResultUtil.success(map.getData());
  }

  private String getOauthUrl() {
    String serverList = discoveryClient.getServices().stream().filter(s -> s.contains("oauth"))
        .flatMap(s -> discoveryClient.getInstances(s).stream()).map(instance -> String
            .format("http://%s:%s/", instance.getHost(), instance.getPort()))
        .collect(Collectors.joining(","));
    log.info("oauth地址:{}", serverList);
    return serverList +"/login";
  }


  /**
   * @param url     请求地址
   * @param builder
   * @return
   */
  public static String sendPostFormData(String url, MultipartEntityBuilder builder) {
    String StringResult = "";
    //不需要手动关闭httpClient
    HttpClient httpClient = HttpClientBuilder.create().build();
    HttpPost httpPost = new HttpPost(url);

    // 构建form-data请求体
    HttpEntity entity = builder.build();
    httpPost.setEntity(entity);

    // 发送请求并获取响应
    HttpResponse response = null;
    try {
      response = httpClient.execute(httpPost);
      HttpEntity responseEntity = response.getEntity();
      StringResult = EntityUtils.toString(responseEntity);
    } catch (IOException e) {
      StringResult = "errorException:" + e.getMessage();
      e.printStackTrace();
    }
    return StringResult;
  }
}

